#include "uart_operation.h"

int UART0_Open(char* port)
{
	int fd;
	fd = open (port,O_RDWR|O_NOCTTY|O_NDELAY);
	if(fd < 0)
	{
		perror("can't Open Serial Port");
		return -1;
	}
	if(fcntl(fd,F_SETFL,0)<0)  //设置给arg描述符状态标志，可以更改的几个标志是：O_APPEND，O_NONBLOCK，O_SYNC 和 O_ASYNC
	{
		printf("fcntl failed!\n");
		return -1;
	}
	else
	{
		 printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
	}
	 //测试是否为终端设备
    if(0 == isatty(fd))
	{  
        printf("standard input is not a terminal device\n");  
        return -1;
	}
	else
	{  
        printf("isatty success!\n");  
    }                
    printf("fd->open=%d\n",fd);  
		 return fd;
}
// 串口的关闭
void UART0_Close(int fd)
{
	close(fd);
}
//设置串口数据位，停止位,校验位
void init_tty(int fd)
{
	struct termios newtio;
	struct termios oldtio;
	bzero(&newtio,sizeof(struct termios));//全部初始化为零
	tcgetattr(fd,&oldtio);//获得 原有的数据保存到oldtio里
	newtio.c_cflag |= CLOCAL | CREAD;//接受使能  
	cfsetispeed(&newtio,B115200);//设置输入速度
	cfsetospeed(&newtio,B115200);// 设置输出速度
	//printf("c_cflag=%x\n",newtio.c_cflag);
	newtio.c_cflag &= ~CSIZE;//对应比特位清零
	//printf("c_cflag=%x\n",newtio.c_cflag);
	newtio.c_cflag |= CS8;
	//printf("c_cflag=%x\n",newtio.c_cflag);
	
	//设置无校验
	newtio.c_cflag &= ~PARENB;
	newtio.c_iflag &= ~INPCK;
	//设置停止位
	newtio.c_cflag &= ~CSTOPB;
	//设置等待时间和接受字符
	newtio.c_cc[VTIME] = 0;
	newtio.c_cc[VMIN] = 0;
	//设置原始模式
	newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	newtio.c_lflag &= ~OPOST;
	//刷新串口缓冲
	tcflush(fd,TCIOFLUSH);
	//设置新的串口属性
	tcsetattr(fd,TCSANOW,&newtio);
}


//串口发数据
int UART0_send(int fd,char*send_buf,int data_len)
{
	int len = 0;
	len = write(fd,send_buf,data_len);
	if(len == data_len)
	{
		return len;
	}
	else
	{
		tcflush(fd,TCOFLUSH);
		return -1;
	}
}


int UART0_Recv(int fd, char *rcv_buf,int data_len, ENV* penv, CARD* pcard)  
{  
	int len,fs_sel;  
	fd_set fs_read;  //读变化的集合
			     
	struct timeval time;  //设置超时
				     
	FD_ZERO(&fs_read);  
    FD_SET(fd,&fs_read);  	//把ziggbi文件描述符加入到集合中
						     
    time.tv_sec = 5;  			//select超时，则返回；
	time.tv_usec = 0;
	
	//用select 实现异步
	fs_sel = select(fd+1,&fs_read,NULL,NULL,&time);  
	if(fs_sel < 0)
	{
		perror("select");
		return -1;
	}
	else  if ( 0 == fs_sel)
	{  
		printf("time out\n");  
		return -1;  
    }   
    else   										//只有监控了一个文件描述符，所以select返回时，不需要判断；
	{ 
		len = read(fd,rcv_buf,data_len);  
		rcv_buf[len] = '\0';
		printf("recv_buf:%s,begin to analysis\n",rcv_buf);       		//是不是*rcv_buf
		analysis_recv_buf(rcv_buf ,penv, pcard);
		return len;
	} 
}


//env 和	card

int analysis_recv_buf(char *buf, ENV *penv, CARD *pcard)			// tem:35.5 hum:40.5 				Cid:121839142a
{
    if(NULL == buf)
    {
        return -1;
    }
    int i = 0;
    char save[32] = {0};
    char *p = buf;
    p += 4;
    
    if(!strncmp(buf,"Tem:",4))
    {
        while(*p != ' ')		//湿度
        {
            save[i++] = *p;
            p++;
        }
        float tem = atof(save);
        printf("tmp = %f\n",tem);
        penv->temperature = tem;
        memset(save,0,sizeof(save));
        p += 5;
        i = 0;
		
        while(*p != ' ')		//湿度
        {
            save[i++] = *p;
            p++;
        }
		
        float hum = atof(save);
        penv->humidity = hum;
        printf("%.1f,%.1f\n",penv->temperature,penv->humidity);
				
		p += 5;
		
		//printf("*p = %c\n",*p);
		
		if(*p != ' ')			//卡号
		{
			strncpy(pcard->card_no, p,strlen(p)+1);
			printf("Cid:%s\n",pcard->card_no);
		}
		return 0;
    }
}
